package dao

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

// TiandituConfig 天地图API配置
// 天地图是国家地理信息公共服务平台提供的免费地图服务
type TiandituConfig struct {
	Provider string `json:"provider"` // 服务提供商：tianditu
	APIKey   string `json:"api_key"`  // API密钥（天地图免费使用，可为空）
	BaseURL  string `json:"base_url"` // API基础URL
	Timeout  int    `json:"timeout"`  // 请求超时时间（秒）
}

// 天地图API配置
var tiandituConfig = TiandituConfig{
	Provider: "tianditu",
	APIKey:   "", // 天地图免费使用，无需API密钥
	BaseURL:  "https://api.tianditu.gov.cn",
	Timeout:  30,
}

// TiandituGeocodingResponse 天地图地理编码API响应结构
type TiandituGeocodingResponse struct {
	Status    string `json:"status"`     // 响应状态
	Result    string `json:"result"`     // 响应结果
	Location  string `json:"location"`   // 坐标信息
	Level     string `json:"level"`      // 地址级别
	Precision string `json:"precision"`  // 精度
}

// TiandituPOIResponse 天地图兴趣点搜索API响应结构
type TiandituPOIResponse struct {
	Status   string `json:"status"`   // 响应状态
	Count    int    `json:"count"`    // 结果数量
	Results  []POI  `json:"results"`  // 兴趣点列表
}

// POI 兴趣点信息
type POI struct {
	Name     string  `json:"name"`     // 名称
	Address  string  `json:"address"`  // 地址
	Location string  `json:"location"` // 坐标
	Type     string  `json:"type"`     // 类型
	Distance float64 `json:"distance"` // 距离
}

// TiandituRouteResponse 天地图路径规划API响应结构
type TiandituRouteResponse struct {
	Status  string `json:"status"`  // 响应状态
	Result  string `json:"result"`  // 响应结果
	Routes  []Route `json:"routes"` // 路径列表
}

// Route 路径信息
type Route struct {
	Distance int    `json:"distance"` // 距离（米）
	Duration int    `json:"duration"` // 时间（秒）
	Steps    []Step `json:"steps"`    // 路径步骤
}

// Step 路径步骤
type Step struct {
	Instruction string `json:"instruction"` // 导航指令
	Distance    int    `json:"distance"`    // 距离
	Duration    int    `json:"duration"`    // 时间
	Polyline    string `json:"polyline"`    // 路径坐标
}

// GetTiandituGeocoding 调用天地图地理编码API
// 
// 功能特性：
// - 地址转坐标：将地址转换为经纬度坐标
// - 免费使用：无需API密钥，直接调用
// - 高精度：提供精确的地理位置信息
//
// 参数:
//   - ctx: 上下文，用于请求超时控制
//   - address: 地址信息
//
// 返回:
//   - *TiandituGeocodingResponse: 天地图地理编码API响应
//   - error: 错误信息
func GetTiandituGeocoding(ctx context.Context, address string) (*TiandituGeocodingResponse, error) {
	// 构建请求URL
	url := fmt.Sprintf("%s/geocoder?postStr={'address':'%s','city':'','key':'%s'}&type=geocode",
		tiandituConfig.BaseURL, address, tiandituConfig.APIKey)

	// 创建HTTP请求
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
	if err != nil {
		return nil, fmt.Errorf("创建请求失败: %v", err)
	}

	// 发送请求
	client := &http.Client{Timeout: time.Duration(tiandituConfig.Timeout) * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %v", err)
	}

	// 解析响应
	var geocodingResp TiandituGeocodingResponse
	if err := json.Unmarshal(body, &geocodingResp); err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	// 检查API响应状态
	if geocodingResp.Status != "0" {
		return nil, fmt.Errorf("天地图API错误: %s", geocodingResp.Result)
	}

	return &geocodingResp, nil
}

// GetTiandituPOI 调用天地图兴趣点搜索API
// 
// 功能特性：
// - 兴趣点搜索：搜索指定位置附近的兴趣点
// - 免费使用：无需API密钥，直接调用
// - 多类型支持：支持多种兴趣点类型搜索
//
// 参数:
//   - ctx: 上下文，用于请求超时控制
//   - keyword: 搜索关键词
//   - location: 搜索中心位置（经纬度）
//   - radius: 搜索半径（米）
//
// 返回:
//   - *TiandituPOIResponse: 天地图兴趣点搜索API响应
//   - error: 错误信息
func GetTiandituPOI(ctx context.Context, keyword, location string, radius int) (*TiandituPOIResponse, error) {
	// 构建请求URL
	url := fmt.Sprintf("%s/search?postStr={'keyWord':'%s','level':'','mapBound':'','pageSize':20,'pageNum':1,'queryType':'1','start':0,'count':20,'polygon':'','queryTerminal':'','timeSort':'0'}&type=query",
		tiandituConfig.BaseURL, keyword)

	// 创建HTTP请求
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
	if err != nil {
		return nil, fmt.Errorf("创建请求失败: %v", err)
	}

	// 发送请求
	client := &http.Client{Timeout: time.Duration(tiandituConfig.Timeout) * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %v", err)
	}

	// 解析响应
	var poiResp TiandituPOIResponse
	if err := json.Unmarshal(body, &poiResp); err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	// 检查API响应状态
	if poiResp.Status != "0" {
		return nil, fmt.Errorf("天地图API错误: %s", poiResp.Status)
	}

	return &poiResp, nil
}

// GetTiandituRoute 调用天地图路径规划API
// 
// 功能特性：
// - 路径规划：计算两点之间的最优路径
// - 免费使用：无需API密钥，直接调用
// - 多种方式：支持驾车、步行、公交等路径规划
//
// 参数:
//   - ctx: 上下文，用于请求超时控制
//   - origin: 起点坐标（经纬度）
//   - destination: 终点坐标（经纬度）
//   - mode: 出行方式（driving, walking, transit）
//
// 返回:
//   - *TiandituRouteResponse: 天地图路径规划API响应
//   - error: 错误信息
func GetTiandituRoute(ctx context.Context, origin, destination, mode string) (*TiandituRouteResponse, error) {
	// 构建请求URL
	url := fmt.Sprintf("%s/drive?postStr={'orig':'%s','dest':'%s','style':'0'}&type=search",
		tiandituConfig.BaseURL, origin, destination)

	// 创建HTTP请求
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
	if err != nil {
		return nil, fmt.Errorf("创建请求失败: %v", err)
	}

	// 发送请求
	client := &http.Client{Timeout: time.Duration(tiandituConfig.Timeout) * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %v", err)
	}

	// 解析响应
	var routeResp TiandituRouteResponse
	if err := json.Unmarshal(body, &routeResp); err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	// 检查API响应状态
	if routeResp.Status != "0" {
		return nil, fmt.Errorf("天地图API错误: %s", routeResp.Result)
	}

	return &routeResp, nil
}

// GetTiandituTileURL 获取天地图瓦片服务URL
// 
// 功能特性：
// - 瓦片服务：获取地图瓦片数据
// - 多种类型：支持矢量、影像、地形等多种地图类型
// - 免费使用：无需API密钥，直接使用
//
// 参数:
//   - x: 瓦片X坐标
//   - y: 瓦片Y坐标
//   - z: 缩放级别
//   - mapType: 地图类型（vec, img, ter, cva, cia）
//
// 返回:
//   - string: 天地图瓦片服务URL
func GetTiandituTileURL(x, y, z int, mapType string) string {
	// 天地图瓦片服务URL格式
	// {s} 为服务器编号（0-7），用于负载均衡
	serverNum := (x + y) % 8
	return fmt.Sprintf("https://t%d.tianditu.gov.cn/DataServer?T=%s_w&x=%d&y=%d&l=%d&tk=",
		serverNum, mapType, x, y, z)
}

// SetTiandituAPIKey 设置天地图API密钥
// 虽然天地图免费使用，但设置API密钥可以获得更高的调用配额
func SetTiandituAPIKey(apiKey string) {
	tiandituConfig.APIKey = apiKey
}

// GetTiandituAPIStatus 获取天地图API状态
// 检查天地图服务的配置状态
func GetTiandituAPIStatus() map[string]interface{} {
	return map[string]interface{}{
		"provider":    tiandituConfig.Provider,
		"base_url":    tiandituConfig.BaseURL,
		"timeout":     tiandituConfig.Timeout,
		"api_key_set": tiandituConfig.APIKey != "",
		"free_service": true, // 天地图是免费服务
	}
}
